import cv2
import numpy as np
import requests
import json
import re
# import gradio as gr
import os
from skimage.morphology import skeletonize
import matplotlib.pyplot as plt
from io import BytesIO
import base64
from PIL import Image
import math
from config import *

"""实体图ocr识别长宽以及上部和底部数字求和"""
class UrlOcr:    
    # """1.url识别转换"""
    # def extract_file_name(url):
    #     match = re.search(r'standard_(.*\.png)', url)
    #     if match:
    #         return match.group(1)
    #     else:
    #         raise ValueError("File name extraction failed")
    
    # def generate_urls(file_name):
    #     if file_name:
    #         floorplan_url = f"https://ke-image.ljcdn.com/hdic-frame/standard_{file_name}.1000x750.jpg?from=ke.com"
    #         return floorplan_url
    #     else:
    #         raise ValueError("File name is not extracted")
    def __init__(self):
        pass

    def download_image(self):
        try:
            response = requests.get(self.url)
            response.raise_for_status()  # Raise HTTPError for bad response status
            image_array = np.asarray(bytearray(response.content), dtype=np.uint8)
            image = cv2.imdecode(image_array, cv2.IMREAD_COLOR)
            if image is None:
                raise ValueError("Failed to decode image")
            return image
        except requests.exceptions.RequestException as e:
            print(f"Error downloading image from {self.url}: {e}")
            return None
        except Exception as e:
            print(f"Error processing image: {e}")
            return None
    """3.OCR识别"""
    def perform_ocr(self, image):
        temp_image_path = 'temp_image.jpg'
        cv2.imwrite(temp_image_path, image)
        # # 显示临时图像
        # img_to_show = cv2.imread(temp_image_path)
        # cv2.imshow('Temporary Image', img_to_show)
        # cv2.waitKey(0)
        # cv2.destroyAllWindows()
        
        with open(temp_image_path, 'rb') as file:
            files = {'file': file}
            data = {'Text': 'string'}
            response = requests.post(ocrUrl, files=files, data=data)

        os.remove(temp_image_path)

        if response.status_code == 200:
            try:
                ocr_result = response.json()
                # print(f"OCR结果: {ocr_result}")
                if "DataBody" in ocr_result:
                    extracted_values = []
                    for item in ocr_result["DataBody"]:
                        for text in item[1]:
                            if isinstance(text, str):
                               # 查找连续的6位数字
                                long_numbers = re.findall(r'\d{5,9}', text)
                                if long_numbers:
                                    extracted_values.extend(long_numbers)
                                else:
                                    # 查找3到4位数字
                                    numbers = re.findall(r'\d{3,4}', text)
                                    extracted_values.extend(numbers)                            
                            # if isinstance(text, str):
                            #     numbers = re.findall(r'\d{3,4}', text)
                            #     extracted_values.extend(numbers)
                    # print(f"Extracted values: {extracted_values}")
                    return ocr_result, extracted_values
                else:
                    return "响应中不包含DataBody", None
            except json.JSONDecodeError:
                return "响应内容不是有效的JSON格式", None
        else:
            return f"请求失败，状态码: {response.status_code}", None

    def process_image(self, image):
        gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        lower_white = np.array([200, 200, 200])
        upper_white = np.array([255, 255, 255])
        white_mask = cv2.inRange(image, lower_white, upper_white)

        lower_black = np.array([0, 0, 0])
        upper_black = np.array([50, 50, 50])
        black_mask = cv2.inRange(image, lower_black, upper_black)

        kernel = np.ones((5, 5), np.uint8)
        white_mask = cv2.morphologyEx(white_mask, cv2.MORPH_OPEN, kernel)
        white_mask = cv2.morphologyEx(white_mask, cv2.MORPH_CLOSE, kernel)
        black_mask = cv2.morphologyEx(black_mask, cv2.MORPH_OPEN, kernel)
        black_mask = cv2.morphologyEx(black_mask, cv2.MORPH_CLOSE, kernel)
        
        # contours_image = image.copy()
        wall_contours, _ = cv2.findContours(black_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
        # cv2.drawContours(contours_image, wall_contours, -1, (0, 255, 0), 1)
        # cv2.imshow('Contours on Black Mask', contours_image)
        # cv2.waitKey(0)
        # cv2.destroyAllWindows()
        #以前150现在改成400，大图问题
        MIN_CONTOUR_AREA = 400
        filtered_wall_contours = [cnt for cnt in wall_contours if cv2.contourArea(cnt) > MIN_CONTOUR_AREA]
        x, y, w, h = cv2.boundingRect(np.concatenate(filtered_wall_contours))
        xmin = x
        xmax = x + w
        ymin = y
        ymax = y + h
        max_min = (xmin, ymin, xmax, ymax)

        cropped_image = image[y:y+h, x:x+w]

        image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
        cropped_image_rgb = cv2.cvtColor(cropped_image, cv2.COLOR_BGR2RGB)
        
        # # 裁剪上部分图像
        # cropped_image_top = image[:y, x:x+w]
        # # 裁剪下部分图像
        # cropped_image_bottom = image[y+h:, x:x+w]
        # ocr_result_top, extracted_values_top = self.perform_ocr(cropped_image_top)
        # ocr_result_bottom, extracted_values_bottom = self.perform_ocr(cropped_image_bottom)

        

        # # 计算顶部和底部提取的数字之和（假设 extracted_values_top 和 extracted_values_bottom 是数字列表）
        # first_row_sum = sum(int(num) for num in extracted_values_top) if extracted_values_top else 0
        # last_row_sum = sum(int(num) for num in extracted_values_bottom) if extracted_values_bottom else 0     
        
        # # 裁剪上部分图像
        # cropped_image_top = image[:y, x:x+w] if y > 0 else None
        # # 裁剪下部分图像
        # cropped_image_bottom = image[y+h:, x:x+w] if y+h < image.shape[0] else None

        # first_row_sum = 0
        # last_row_sum = 0

        # if cropped_image_top is not None and cropped_image_top.size > 0:
        #     ocr_result_top, extracted_values_top = self.perform_ocr(cropped_image_top)
        #     first_row_sum = sum(int(num) for num in extracted_values_top) if extracted_values_top else 0

        # if cropped_image_bottom is not None and cropped_image_bottom.size > 0:
        #     ocr_result_bottom, extracted_values_bottom = self.perform_ocr(cropped_image_bottom)
        #     last_row_sum = sum(int(num) for num in extracted_values_bottom) if extracted_values_bottom else 0

        # 裁剪上部分图像
        cropped_image_top = image[:y, x:x+w] if y > 0 else None
        # 裁剪下部分图像
        cropped_image_bottom = image[y+h:, x:x+w] if y+h < image.shape[0] else None

        first_row_sum = 0
        last_row_sum = 0

        # if cropped_image_top is not None and cropped_image_top.size > 0:
        #     ocr_result_top, extracted_values_top = self.perform_ocr(cropped_image_top)
        #     first_row_sum = sum(int(num) for num in extracted_values_top) if extracted_values_top else 0

        # if cropped_image_bottom is not None and cropped_image_bottom.size > 0:
        #     ocr_result_bottom, extracted_values_bottom = self.perform_ocr(cropped_image_bottom)
        #     last_row_sum = sum(int(num) for num in extracted_values_bottom) if extracted_values_bottom else 0
        top_value_isok = True
        if cropped_image_top is not None and cropped_image_top.size > 0:
            ocr_result_top, extracted_values_top = self.perform_ocr(cropped_image_top)
            if any(len(num) in [5, 6, 7, 8, 9] for num in extracted_values_top):
                top_value_isok = False
            else:
                first_row_sum = sum(int(num) for num in extracted_values_top if len(num) not in [5, 6, 7, 8, 9])
        if first_row_sum == 0:
            top_value_isok = False
        # print(first_row_sum)
        bottom_value_isok = True
        if cropped_image_bottom is not None and cropped_image_bottom.size > 0:
            ocr_result_bottom, extracted_values_bottom = self.perform_ocr(cropped_image_bottom)
            if any(len(num) in [5, 6, 7, 8, 9] for num in extracted_values_bottom):
                bottom_value_isok = False
            else:
                last_row_sum = sum(int(num) for num in extracted_values_bottom if len(num) not in [5, 6, 7, 8, 9])
        if last_row_sum == 0:
            bottom_value_isok = False
        # print(last_row_sum)      

        if top_value_isok and not bottom_value_isok:
            last_row_sum = first_row_sum
        elif bottom_value_isok and not top_value_isok:
            first_row_sum = last_row_sum
        elif not bottom_value_isok and not top_value_isok:
            first_row_sum = 0
            last_row_sum = 0
        
        if abs(first_row_sum-last_row_sum) > 1000:
            first_row_sum = min(first_row_sum,last_row_sum)
            last_row_sum = first_row_sum

        return first_row_sum, last_row_sum, w, h, max_min       

    """5.gradio接口返回这些需要的字段"""
    def process_urls(self,url):
        self.url = url
        # file_name = WireFrames.extract_file_name(url)
        # wireframes_url = WireFrames.generate_urls(file_name)
        image = self.download_image()
        if image is None:
            raise ValueError("Failed to download or process the image")
        first_row_sum, last_row_sum, w, h, max_min = self.process_image(image)
        return first_row_sum, last_row_sum, w, h, max_min     
        #return floorplan_rgb, cropped_image_rgb, first_row_sum, last_row_sum, max_min, wall_contours, door_contours

    """6.图片转换"""
    def image_to_base64(self, image):
        _, buffer = cv2.imencode('.jpg', image)
        img_base64 = base64.b64encode(buffer).decode('utf-8')
        return img_base64

# url = 'https://ke-image.ljcdn.com/hdic-frame/standard_477d6cbd-9d4f-42cf-b819-4082813fc63a.png.1440x1080.jpg?from=ke.com'
# url = 'https://ke-image.ljcdn.com/hdic-frame/standard_477d6cbd-9d4f-42cf-b819-4082813fc63a.png.1000x750.jpg?from=ke.com'
# UrlOcr = UrlOcr()
# first_row_sum, last_row_sum, w, h, max_min  = UrlOcr.process_urls(url)
# print(f"first_row_sum: {first_row_sum}")
# print(f"last_row_sum: {last_row_sum}")
# print(f"w: {w}")
# print(f"h: {h}")
# print(f"max_min: {max_min}")